package com.cqyanyu.yanyu.view.recyclerView;

import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;

import org.xutils.common.util.LogUtil;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by cheng on 2016/7/16.
 */
public class YRecyclerViewAdapter extends RecyclerView.Adapter<YViewHolder> {
    protected Map<Integer, Class> viewTypeHolder = new HashMap<Integer, Class>();
    protected Map<Integer, Integer> spanCount;
    protected Map<Integer, OnItemViewType> onItemViewTypeMap;
    protected List data;
    protected List header;

    protected boolean loadMore = true;
    protected boolean noDataTips = true;

    public YRecyclerViewAdapter() {
        viewTypeHolder.put(YLoadMoreHolder.class.hashCode(), YLoadMoreHolder.class);
        viewTypeHolder.put(YNoDataTipsHolder.class.hashCode(), YNoDataTipsHolder.class);
    }


    @Override
    public YViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        Class holderClass = viewTypeHolder.get(viewType);
        if (holderClass == null) {
            Log.e("YRecyclerViewAdapter", "该类型的holder不存在");
            return null;
        }
        return getViewHolder(holderClass, parent);
    }

    @Override
    public void onBindViewHolder(YViewHolder holder, int position) {
        holder.setPosition(position);
        holder.onBindViewHolder(getItemData(position));
    }

    @Override
    public int getItemCount() {
        int Count = getDataSize();
        Count += getHeaderSize();
        if (Count == 0 && noDataTips) {
            return 1;
        }
        if (loadMore) {
            Count += 1;
        }
        return Count;
    }

    private int getDataSize() {
        return data == null ? 0 : data.size();
    }

    private int getHeaderSize() {
        return header == null ? 0 : header.size();
    }

    public Object getItemData(int index) {
        if (getHeaderSize() > index) {
            return header.get(index);
        } else {
            index = index - getHeaderSize();
            if (getDataSize() > index) {
                return data.get(index);
            }
        }
        return null;
    }

    @Override
    public int getItemViewType(int position) {
        //如果时最后一条 且开启了加载更多 返回 加载更多
        if (position + 1 == getItemCount() && loadMore) {
            return YLoadMoreHolder.class.hashCode();
        }
        //如果data 为空 返回没有数据提示
        if (getDataSize() + getHeaderSize() == 0) {
            return YNoDataTipsHolder.class.hashCode();
        }
        Class classz = getItemData(position).getClass();
        int viewType = classz.hashCode();//获取当前数据的hash值作为type
        LogUtil.d("getItemViewType数据类型" + classz.getName());
        if (onItemViewTypeMap != null) {
            //获得 对应Entity 的OnItemViewType接口
            OnItemViewType onItemViewType = onItemViewTypeMap.get(viewType);
            if (onItemViewType != null) {
                Class viewTypeHolderClass = onItemViewType.getViewTypeHolderClass(getItemData(position), position);//用holder的Class.hashCode作为type
                viewType = viewTypeHolderClass.hashCode();
                if (viewTypeHolder.get(viewType) == null)
                    viewTypeHolder.put(viewType, viewTypeHolderClass);
            }
        }
        return viewType;
    }

    /**
     * 根据Class实例化对象
     *
     * @param classz
     * @param parent
     * @return
     */
    protected YViewHolder getViewHolder(Class classz, ViewGroup parent) {
        YViewHolder viewHolder = null;
        try {
            Constructor c1 = null;
            try {
                c1 = classz.getDeclaredConstructor(new Class[]{View.class});
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }
            c1.setAccessible(true);
            try {
                viewHolder = (YViewHolder) c1.newInstance(new Object[]{parent});
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return viewHolder;
    }

    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
        RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();
        if (manager instanceof GridLayoutManager) {
            final GridLayoutManager gridManager = ((GridLayoutManager) manager);
            try {
                gridManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
                    @Override
                    public int getSpanSize(int position) {
                        int spc = gridManager.getSpanCount();
                        if (spc == 1 || spanCount == null) {
                            return 1;
                        }
                        //如果data.size<=postition时 可能是load或headview 故返回 跨越宽度为 总列数
                        if (getDataSize() + getHeaderSize() <= position) {
                            return spc;
                        }
                        int index = getItemData(position).getClass().hashCode();
                        Object s = spanCount.get(index);
                        if (s == null) {
                            return 1;
                        } else {
                            int x = spanCount.get(index).intValue();
                            return x;
                        }
                    }
                });
            } catch (Exception e) {
            }
        }
    }

    /**
     * 绑定指定数据类型的 viewHolder
     *
     * @param entityClass     数据实体类的class
     * @param viewholderClass viewHolder的实体类
     */
    public void bindItemHolder(Class entityClass, Class viewholderClass) {
        viewTypeHolder.put(entityClass.hashCode(), viewholderClass);
    }

    /**
     * 设置对应类型的cell的跨度
     * spanSize表示一个item的跨度，跨度了多少个span。
     *
     * @param entityClass
     * @param spanSize
     */
    public void setCellSpanCount(Class entityClass, int spanSize) {
        if (spanCount == null) {
            spanCount = new HashMap<Integer, Integer>();
        }
        this.spanCount.put(entityClass.hashCode(), spanSize);
    }

    /**
     * itemviewType接口
     *
     * @param entityClass    数据实体类class
     * @param onItemViewType type接口
     */
    public void setOnItemViewType(Class entityClass, OnItemViewType onItemViewType) {
        if (this.onItemViewTypeMap == null) {
            this.onItemViewTypeMap = new HashMap<Integer, OnItemViewType>();
        }
        this.onItemViewTypeMap.put(entityClass.hashCode(), onItemViewType);
    }

    /**
     * 设置data，可以是多个不同类型的List
     *
     * @param lists List列表
     */
    public void setData(List... lists) {
        this.data = new ArrayList();
        for (List list : lists) {
            this.data.addAll(list);
        }
        notifyDataSetChanged();
    }

    /**
     * 添加list数据
     *
     * @param list
     */
    public void addData(List list) {
        this.data.addAll(list);
        notifyDataSetChanged();
    }

    /**
     * 添加单项数据
     *
     * @param object
     */
    public void addItemData(Object object) {
        if (this.data == null) {
            this.data = new ArrayList();
        }
        this.data.add(object);
        notifyDataSetChanged();
    }

    /**
     * 设置header 的list数据
     *
     * @param headerlist
     */
    public void setHeaderList(List headerlist) {
        this.header = headerlist;
        notifyDataSetChanged();
    }

    /**
     * 更新header
     *
     * @param index  指定序号
     * @param object
     */
    public void setHeader(int index, Object object) {
        if (this.header == null) {
            this.header = new ArrayList();
        }
        if (this.header.size() <= index) {
            this.header.add(object);
        } else {
            this.header.set(index, object);
        }

        notifyDataSetChanged();
    }

    public void addHeader(Object object) {
        if (this.header == null) {
            this.header = new ArrayList();
        }
        this.header.add(object);

        notifyDataSetChanged();
    }

    public void addHeader(int index, Object object) {
        if (this.header == null) {
            this.header = new ArrayList();
        }
        this.header.add(index, object);
        notifyDataSetChanged();
    }


    /**
     * 设置加载更多状态
     *
     * @param loadMore
     */
    public void setLoadMore(boolean loadMore) {
        this.loadMore = loadMore;
        notifyDataSetChanged();
    }

    /**
     * 加载更多状态
     *
     * @return
     */
    public boolean isLoadMore() {
        return loadMore;
    }

    /**
     * 设置是否没有数据是提示
     *
     * @param noDataTips
     */
    public void setNoDataTips(boolean noDataTips) {
        this.noDataTips = noDataTips;
    }

    /**
     * 没有数据是提示
     *
     * @return
     */
    public boolean isNoDataTips() {
        return noDataTips;
    }

    public List getData() {
        return data;
    }

    public interface OnItemViewType<T> {
        public Class getViewTypeHolderClass(T itemData, int postion);

    }
}
